home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
multi_v.arc
/
DRIVER.ASM
next >
Wrap
Assembly Source File
|
1988-04-19
|
12KB
|
423 lines
page 66,132
; *****************************************************
; * PROLOG *
; * This is an installable device driver for an *
; * in storage diskette (virtual) with 180K capacity. *
; *****************************************************
;
CSEG SEGMENT PARA PUBLIC 'CODE'
;
; M A C R O ( S )
;
STATUS MACRO STATE,ERR,RC
IFIDN <STATE>,<DONE>
OR ES:WORD PTR SRH_STA_FLD[BX],0100H
ENDIF
IFIDN <STATE>,<BUSY>
OR ES:WORD PTR SRH_STA_FLD[BX],0200H
ENDIF
IFIDN <ERR>,<ERROR>
OR ES:WORD PTR SRH_STA_FLD[BX],1000H
ENDIF
IFNB <RC>
OR ES:WORD PTR SRH_STA_FLD[BX],RC
ENDIF
ENDM
;
; E Q U A T E S
;
; READ/WRITE
;
SRH EQU 0 ;
SRH_LEN EQU 13 ;
SRH_LEN_FLD EQU SRH ;
SRH_UCD_FLD EQU SRH+1 ;
SRH_CCD_FLD EQU SRH+2 ;
SRH_STA_FLD EQU SRH+3 ;
SRH_RES_FLD EQU SRH+5 ;
;
MD EQU SRH+SRH_LEN ;
MD_LEN EQU 1 ;
DTA EQU MD+MD_LEN ;
DTA_LEN EQU 4 ;
COUNT EQU DTA+DTA_LEN ;
COUNT_LEN EQU 2 ;
SSN EQU COUNT+COUNT_LEN ;
SSN_LEN EQU 2 ;
;
; MEDIA CHECK
;
RET_BYTE EQU MD+MD_LEN ;
;
; BUILD BPB
;
BPBA_PTR EQU DTA+DTA_LEN ;
BPBA_PTR_LEN EQU 4 ;
;
; INIT
;
UNITS EQU SRH+SRH_LEN
UNITS_LEN EQU 1
BR_ADDR_0 EQU UNITS+UNITS_LEN
BR_ADDR_1 EQU BR_ADDR_0+2
BR_ADDR_LEN EQU 4
BPB_PTR_OFF EQU BR_ADDR_0+BR_ADDR_LEN
BPB_PTR_SEG EQU BPB_PTR_OFF+2
;
;
VDSK PROC FAR
ASSUME CS:CSEG,ES:CSEG,DS:CSEG
BEGIN:
START EQU $
; S P E C I A L D E V I C E H E A D E R
NEXT_DEV DD -1 ;
ATTRIBUTE DW 2000H ;
STRATEGY DW DEV_STRATEGY ;
INTERRUPT DW DEV_INT ;
DEV_NAME DB 3 ;
DB 7 DUP(?) ;
;
RH_OFF DW ? ;
RH_SEG DW ? ;
; BIOS PARAMETER BLOCK
BPB EQU $ ;
SEC_SIZE DW 512 ;
DB 1 ;
DW 1 ;
DB 1 ;
DW 32 ;
NUM_SEC DW 127 ; NOTE - must be less than 128
DB 0FCH ; or arithmetic overflows.
DW 1 ;
;
BPB_PTR DW BPB ;
DW BPB ;
DW BPB ;
; CURRENT VIRTUAL DISK INFORMATION
TOTAL DW ? ;
VERIFY DB 0 ;
START_SEC DW 0 ;
VDISK_PTR DW 0 ;
USER_DTA DD ? ;
BOOT_REC EQU $ ;
DB 3 DUP(0) ;
DB 'IBM 2.0' ;
DW 512 ;sector size
DB 1 ;sectors per allocation unit
DW 1 ;reserved sectors
DB 1 ;FATS
DW 32 ;directory entries
DW 127 ;total sectors in image 127 tops
DB 0FCH ;single sided 9 sector
DW 1 ;sectors in FAT
;
; FUNCTION TABLE
;
FUNTAB LABEL BYTE ;
DW INIT ;
DW MEDIA_CHECK ;
DW BUILD_BPB ;
DW IOCTL_IN ;
DW INPUT ;
DW ND_INPUT ;
DW IN_STAT ;
DW IN_FLUSH ;
DW OUTPUT ;
DW OUT_VERIFY ;
DW OUT_FLUSH ;
DW IOCTL_OUT ;
;
; L O C A L P R O C E D U R E S
;
IN_SAVE PROC NEAR
MOV AX,ES:WORD PTR DTA[BX]
MOV CS:USER_DTA,AX
MOV AX,ES:WORD PTR DTA+2[BX]
MOV CS:USER_DTA+2,AX
MOV AX,ES:WORD PTR COUNT[BX]
XOR AH,AH
MOV CS:TOTAL,AX
RET
IN_SAVE ENDP
;
CALC_ADDR PROC NEAR
MOV AX,CS:START_SEC
MOV CX,20H
MUL CX
MOV DX,CS:VDISK_PTR
ADD DX,AX
MOV DS,DX
XOR SI,SI
MOV AX,CS:TOTAL
MOV CX,512
MUL CX
OR AX,AX
JNZ MOVE_IT
MOV AX,0FFFFH
MOVE_IT:
XCHG CX,AX
RET
CALC_ADDR ENDP
;
SECTOR_READ PROC NEAR
CALL CALC_ADDR
MOV ES,CS:USER_DTA+2
MOV DI,CS:USER_DTA
;
; CHECK FOR DTA WRAP IN CASE WE CAME THROUGH VIA VERIFY
;
MOV AX,DI
ADD AX,CX
JNC READ_COPY
MOV AX,0FFFFH
SUB AX,DI
MOV CX,AX
READ_COPY:
REP MOVSB
RET
SECTOR_READ ENDP
;
SECTOR_WRITE PROC NEAR
CALL CALC_ADDR
PUSH DS
POP ES
MOV DI,SI
MOV DS,CS:USER_DTA+2
MOV SI,CS:USER_DTA
;
; CHECK FOR DTA WRAP
;
MOV AX,SI
ADD AX,CX
JNC WRITE_COPY
MOV AX,0FFFFH
SUB AX,SI
MOV CX,AX
WRITE_COPY:
REP MOVSB
RET
SECTOR_WRITE ENDP
;
; D E V I C E S T R A T E G Y
;
DEV_STRATEGY:
MOV CS:RH_SEG,ES
MOV CS:RH_OFF,BX
RET
;
; D E V I C E I N T E R R U P T H A N D L E R
;
DEV_INT:
;
CLD
PUSH DS
PUSH ES
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
;
;
; DO THE BRANCH ACCORDING TO THE FUNCTION PASSED
;
MOV AL,ES:[BX]+2
ROL AL,1
LEA DI,FUNTAB
XOR AH,AH
ADD DI,AX
JMP WORD PTR[DI]
;
; INIT
;
INIT:
PUSH CS
POP DX
LEA AX,CS:VDISK
MOV CL,4
ROR AX,CL
ADD DX,AX
MOV CS:VDISK_PTR,DX
;
PUSH DX
PUSH CX
MOV AX,CS:SEC_SIZE
MUL CS:NUM_SEC ; this limits us to 64kb disks
MOV CL,4
SHR AX,CL
POP CX
POP DX
;
ADD DX,AX
MOV ES:WORD PTR BR_ADDR_0[BX],0
MOV ES:BR_ADDR_1[BX],DX
;
; find the number of disks on the machine and adjust
; "units" to make ram disks end with E:.
PUSH AX
PUSH DX
MOV DL,0
MOV AH,0EH
INT 21H ;AL returns number of logical drives in system.
MOV AH,5 ; put desired last vdisk in AH, A: = 1.
SUB AH,AL
POP DX
MOV ES:BYTE PTR UNITS[BX],AH
POP AX
;
LEA DX,BPB_PTR
MOV ES:BPB_PTR_OFF[BX],DX
MOV ES:BPB_PTR_SEG[BX],CS
MOV ES,CS:VDISK_PTR
XOR DI,DI
LEA SI,BOOT_REC
MOV CX,24
REP MOVSB
MOV CS:WORD PTR START_SEC,1
MOV CS:WORD PTR TOTAL,2
CALL CALC_ADDR
PUSH DS
POP ES
MOV DI,SI
XOR AL,AL
REP STOSB
MOV DS:BYTE PTR [SI],0FCH
MOV DS:BYTE PTR 1[SI],0FFH
MOV DS:BYTE PTR 2[SI],0FFH
PUSH DS
PUSH SI
MOV CS:WORD PTR START_SEC,3
MOV CS:WORD PTR TOTAL,2
CALL CALC_ADDR
PUSH DS
POP ES
MOV DI,SI
POP SI
POP DS
REP MOVSB
MOV CS:WORD PTR START_SEC,5
MOV CS:WORD PTR TOTAL,4
CALL CALC_ADDR
XOR AL, AL
PUSH DS
POP ES
XOR DI,DI
REP STOSB
MOV ES,CS:RH_SEG
MOV BX,CS:RH_OFF
STATUS DONE,NOERROR,0
OR ES:WORD PTR SRH_STA_FLD[BX],0100H
OR ES:WORD PTR SRH_STA_FLD[BX],0
JMP EXIT
;
; MEDIA CHECK
;
MEDIA_CHECK:
MOV ES:BYTE PTR RET_BYTE[BX],1
STATUS DONE,NOERROR,0
OR ES:WORD PTR SRH_STA_FLD[BX],0100H
OR ES:WORD PTR SRH_STA_FLD[BX],0
JMP EXIT
; BUILD BIOS PARAMETER BLOCK
;
BUILD_BPB:
PUSH ES
PUSH BX
MOV CS:WORD PTR START_SEC,0
MOV CS:WORD PTR TOTAL,1
CALL CALC_ADDR
PUSH CS
POP ES
LEA DI,BPB
ADD SI,11
MOV CX,13
REP MOVSB
POP BX
POP ES
LEA DX,BPB
MOV ES:BPBA_PTR[BX],DX
MOV ES:BPBA_PTR+2[BX],CS
MOV ES:DTA[BX],DX
MOV ES:DTA+2[BX],CS
STATUS DONE,NOERROR,0
OR ES:WORD PTR SRH_STA_FLD[BX],0100H
OR ES:WORD PTR SRH_STA_FLD[BX],0
JMP EXIT
;
; THE FOLLOWING ENTRIES ARE FOR NOT SUPPORTED BY THIS DEVICE
;
IOCTL_IN:
IOCTL_OUT:
ND_INPUT:
IN_STAT:
IN_FLUSH:
OUT_STAT:
OUT_FLUSH:
;
; DISK READ
;
INPUT:
CALL IN_SAVE
MOV AX,ES:WORD PTR SSN[BX]
MOV CS:START_SEC,AX
MOV AX,ES:WORD PTR COUNT[BX]
MOV CS:TOTAL,AX
CALL SECTOR_READ
MOV BX,CS:RH_OFF
MOV ES,CS:RH_SEG
STATUS DONE,NOERROR,0
OR ES:WORD PTR SRH_STA_FLD[BX],0100H
OR ES:WORD PTR SRH_STA_FLD[BX],0
JMP EXIT
;
; DISK WRITE
;
OUTPUT:
CALL IN_SAVE
MOV AX,ES:WORD PTR SSN[BX]
MOV CS:START_SEC,AX
MOV AX,ES:WORD PTR COUNT[BX]
MOV CS:TOTAL,AX
CALL SECTOR_WRITE
MOV BX,CS:RH_OFF
MOV ES,CS:RH_SEG
CMP CS:BYTE PTR VERIFY,0
JZ NO_VERIFY
MOV CS:BYTE PTR VERIFY,0
JMP INPUT
NO_VERIFY:
STATUS DONE,NOERROR,0
OR ES:WORD PTR SRH_STA_FLD[BX],0100H
OR ES:WORD PTR SRH_STA_FLD[BX],0
JMP EXIT
OUT_VERIFY:
MOV CS:BYTE PTR VERIFY,1
JMP OUTPUT
;
; COMMON EXIT
;
EXIT:
POP SI
POP DI
POP DX
POP CX
POP BX
POP AX
POP ES
POP DS
RET
E_O_P:
; MACRO TO ALIGN THE VIRTUAL DISK ON A PARAGRAPH BOUNDRY
if ($-START) MOD 16
ORG ($-START)+16-(($-START) MOD 16)
endif
VDISK EQU $
VDSK ENDP
CSEG ENDS
END BEGIN